/**
 * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
 *
 * Description: SLE UART Sample Source. \n
 * Author: @CompanyNameTag \n
 * History: \n
 * 2023-07-17, Create file. \n
 */
#define CONFIG_SLE_UART_BUS 0
//#define CONFIG_UART_TXD    19
//#define CONFIG_UART_RXD    20
#define CONFIG_PWM_USING_V151   1

#define CONFIG_UART_SUPPORT_TX   19
#define CONFIG_UART_SUPPORT_RX   20

#define SLE_UART_TASK_PRIO                  28
#define SLE_UART_TASK_DURATION_MS           2000
#define SLE_UART_BAUDRATE                   115200
#define SLE_UART_TRANSFER_SIZE              256  
#define ERRCODE_SUCC                                        0UL

#define PWM_GPIO0                   0
#define PWM_GPIO1                   2
#define PWM_GPIO2                   3
#define PWM_GPIO3                   1

#define PWM_PIN_MODE0                1
#define PWM_PIN_MODE1                1
#define PWM_PIN_MODE2                1
#define PWM_PIN_MODE3                1

#define PWM_CHANNEL0                0
#define PWM_CHANNEL1                2
#define PWM_CHANNEL2                3
#define PWM_CHANNEL3                1

#define PWM_GROUP_ID_R_forword      0
#define PWM_GROUP_ID_R_backword     1
#define PWM_GROUP_ID_L_forword      2
#define PWM_GROUP_ID_L_backword     3

#define TEST_MAX_TIMES             5
#define DALAY_MS                   100
#define TEST_TCXO_DELAY_1000MS     1000
#define TEST_TCXO_DELAY_2000MS     2000
#define PWM_TASK_STACK_SIZE        0x2000
#define PWM_TASK_PRIO              (osPriority_t)(17)



#include "common_def.h"
#include "soc_osal.h"
#include "ohos_init.h"
#include "pinctrl.h"
#include "uart.h"
#include "hal_uart.h"
#include "sle_device_discovery.h"
#include "sle_low_latency.h"
#include "pwm.h"
#include "osal_debug.h"
#include "cmsis_os2.h"
#include "tcxo.h"
#include "watchdog.h"
#include "stdlib.h"
#include "errcode.h"

#define SLE_UART_TASK_STACK_SIZE            0x600
#include "sle_connection_manager.h"
#include "sle_ssap_client.h"
#include "sle_uart_client.h"

#include "string.h"



     pwm_config_t cfg_no_repeat = {
        50,     //低电平
        200,    //高电平
        0,
        0,
        true
    };




int fsr_data[5] = {550,800,550,550,550};
// tools: split string into an array of int
void split_into_int_array(const char *input, int *output) {
    char inputCopy[256];
    strcpy(inputCopy, input);

    char *token = strtok(inputCopy, ",");
    int index = 0;

    while (token != NULL && index < 5) {
        output[index] = atoi(token);
        token = strtok(NULL, ",");
        index++;
    }
}
// EOF tools




void ControlCar(void)
{     

    if( fsr_data[0]>570&&fsr_data[1]<570&&fsr_data[2]<570&&fsr_data[3]<570) {  
        cfg_no_repeat.high_time = (uint32_t)fsr_data[0]*0.06;
        cfg_no_repeat.low_time = 250- cfg_no_repeat.high_time;
        uapi_pwm_open(PWM_CHANNEL0, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL1, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL2, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL3, &cfg_no_repeat);

        uapi_pwm_start_group(PWM_GROUP_ID_R_forword);
        uapi_pwm_start_group(PWM_GROUP_ID_L_forword);
        printf("PWM_GROUP_ID_forword\r\n"); 
    } else if ( fsr_data[0]<570&& fsr_data[1]>570&& fsr_data[2]<570&& fsr_data[3]<570 ) {  
        cfg_no_repeat.high_time = (uint32_t) fsr_data[2]*0.06;
        cfg_no_repeat.low_time =250- cfg_no_repeat.high_time;
        uapi_pwm_open(PWM_CHANNEL0, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL1, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL2, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL3, &cfg_no_repeat);   
        uapi_pwm_start_group(PWM_GROUP_ID_R_backword);
        uapi_pwm_start_group(PWM_GROUP_ID_L_backword); 
        printf("PWM_GROUP_ID_backword\r\n");           
    } else if (  fsr_data[0]<570&& fsr_data[1]<570&& fsr_data[2]>570&& fsr_data[3]<570 ) {  
        cfg_no_repeat.high_time = (uint32_t) fsr_data[3]*0.06;
        cfg_no_repeat.low_time =250- cfg_no_repeat.high_time;
        uapi_pwm_open(PWM_CHANNEL0, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL1, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL2, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL3, &cfg_no_repeat);
            
        uapi_pwm_start_group(PWM_GROUP_ID_R_backword);
        uapi_pwm_start_group(PWM_GROUP_ID_L_forword); 
        printf("PWM_GROUP_ID_turnright\r\n");         
    } else if ( fsr_data[0]<570&& fsr_data[1]<570&& fsr_data[2]<570&& fsr_data[3]>570 ) {  
        cfg_no_repeat.high_time = (uint32_t) fsr_data[4]*0.06;
        cfg_no_repeat.low_time =250- cfg_no_repeat.high_time;        
        uapi_pwm_open(PWM_CHANNEL0, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL1, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL2, &cfg_no_repeat);
        uapi_pwm_open(PWM_CHANNEL3, &cfg_no_repeat);  
        uapi_pwm_start_group(PWM_GROUP_ID_R_forword);
        uapi_pwm_start_group(PWM_GROUP_ID_L_backword);  

 
        printf("PWM_GROUP_ID_turnleft\r\n"); 
    } else {  
        uapi_pwm_close(PWM_GROUP_ID_R_forword);    
        uapi_pwm_close(PWM_GROUP_ID_R_backword);     
        uapi_pwm_close(PWM_GROUP_ID_L_forword); 
        uapi_pwm_close(PWM_GROUP_ID_L_backword);
        printf("no\r\n"); 
   }
}



static errcode_t pwm_sample_callback(uint8_t channel)
{
    osal_printk("PWM %d, cycle done. \r\n",channel);
    return ERRCODE_SUCC;
} 


static uint8_t g_app_uart_rx_buff[SLE_UART_TRANSFER_SIZE] = { 0 };

static uart_buffer_config_t g_app_uart_buffer_config = {
    .rx_buffer = g_app_uart_rx_buff,
    .rx_buffer_size = SLE_UART_TRANSFER_SIZE
};

static void uart_init_pin(void)
{
    if (CONFIG_SLE_UART_BUS == 0) {
        uapi_pin_set_mode(CONFIG_UART_SUPPORT_TX , PIN_MODE_1);
        uapi_pin_set_mode(CONFIG_UART_SUPPORT_RX, PIN_MODE_1);       
    }else if (CONFIG_SLE_UART_BUS == 1) {
        uapi_pin_set_mode(CONFIG_UART_SUPPORT_TX , PIN_MODE_1);
        uapi_pin_set_mode(CONFIG_UART_SUPPORT_RX, PIN_MODE_1);       
    }
}





static void uart_init_config(void)
{
    uart_attr_t attr = {
        .baud_rate = SLE_UART_BAUDRATE,
        .data_bits = UART_DATA_BIT_8,
        .stop_bits = UART_STOP_BIT_1,
        .parity = UART_PARITY_NONE
    };

    uart_pin_config_t pin_config = {
        .tx_pin = CONFIG_UART_SUPPORT_TX ,
        .rx_pin = CONFIG_UART_SUPPORT_TX ,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(CONFIG_SLE_UART_BUS);
    uapi_uart_init(CONFIG_SLE_UART_BUS, &pin_config, &attr, NULL, &g_app_uart_buffer_config);

}


void sle_uart_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    // osal_printk("\n sle uart received data : %s\r\n", data->data);
    
    osal_printk("\n sle uart received data : ");
    uapi_uart_write(CONFIG_SLE_UART_BUS, (uint8_t *)(data->data), data->data_len, 0);
    osal_printk("\r\n");
    split_into_int_array((char *)data->data, fsr_data);
    osal_printk("%d, %d, %d, %d, %d\r\n", fsr_data[0], fsr_data[1], fsr_data[2], fsr_data[3], fsr_data[4]);

    // osal_printk("%s\r\n", data->data);
}

void sle_uart_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    osal_printk("\n sle uart recived data : %s\r\n", data->data);
    uapi_uart_write(CONFIG_SLE_UART_BUS, (uint8_t *)(data->data), data->data_len, 0);
}

static void sle_uart_client_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
    uint16_t g_sle_uart_conn_id = get_g_sle_uart_conn_id();
    sle_uart_send_param->data_len = length;
    sle_uart_send_param->data = (uint8_t *)buffer;
    ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);
}




static void *sle_uart_client_task(const char *arg)
{
    unused(arg);
    /* UART pinmux. */
    uart_init_pin();

    /* UART init config. */
    uart_init_config();

    uapi_uart_unregister_rx_callback(CONFIG_SLE_UART_BUS);
    errcode_t ret = uapi_uart_register_rx_callback(CONFIG_SLE_UART_BUS,
                                                   UART_RX_CONDITION_FULL_OR_IDLE,
                                                   1, sle_uart_client_read_int_handler);
    sle_uart_client_init(sle_uart_notification_cb, sle_uart_indication_cb);
    
    if (ret != ERRCODE_SUCC) {
        osal_printk("Register uart callback fail.");
        return NULL;
    }

    return NULL;
}

static void sle_uart_entry(void)
{
    osal_task *task_handle = NULL;
    osal_kthread_lock();


    task_handle = osal_kthread_create((osal_kthread_handler)sle_uart_client_task, 0, "SLEUartDongleTask",
                                      SLE_UART_TASK_STACK_SIZE);

    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, SLE_UART_TASK_PRIO);
    }
    osal_kthread_unlock();
} 

/* Run the sle_uart_entry. */
//app_run(sle_uart_entry);

static void *main_task(const char *arg)
{
    UNUSED(arg);

    uapi_pin_set_mode(PWM_GPIO0, PWM_PIN_MODE1);
    uapi_pin_set_mode(PWM_GPIO1, PWM_PIN_MODE1);
    uapi_pin_set_mode(PWM_GPIO2, PWM_PIN_MODE1);
    uapi_pin_set_mode(PWM_GPIO3, PWM_PIN_MODE1);

    uapi_pwm_deinit();
    uapi_pwm_init();
    uapi_pwm_open(PWM_CHANNEL0, &cfg_no_repeat);
    uapi_pwm_open(PWM_CHANNEL1, &cfg_no_repeat);
    uapi_pwm_open(PWM_CHANNEL2, &cfg_no_repeat);
    uapi_pwm_open(PWM_CHANNEL3, &cfg_no_repeat);

    uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
    uapi_pwm_unregister_interrupt(PWM_CHANNEL0);
    uapi_pwm_unregister_interrupt(PWM_CHANNEL1);
    uapi_pwm_unregister_interrupt(PWM_CHANNEL2);
    uapi_pwm_unregister_interrupt(PWM_CHANNEL3);

    uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
    uapi_pwm_register_interrupt(PWM_CHANNEL0, pwm_sample_callback);
    uapi_pwm_register_interrupt(PWM_CHANNEL1, pwm_sample_callback);
    uapi_pwm_register_interrupt(PWM_CHANNEL2, pwm_sample_callback);
    uapi_pwm_register_interrupt(PWM_CHANNEL3, pwm_sample_callback);
    uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
    uint8_t channel_id_r_forword[1] = {PWM_CHANNEL0}; 
    uint8_t channel_id_r_backword[1] = {PWM_CHANNEL1}; 
    uint8_t channel_id_l_forword[1] = {PWM_CHANNEL3}; 
    uint8_t channel_id_l_backword[1] = {PWM_CHANNEL2}; 
    uapi_pwm_set_group(PWM_GROUP_ID_R_forword, channel_id_r_forword, 1);  
    uapi_pwm_set_group(PWM_GROUP_ID_R_backword, channel_id_r_backword, 1);  
    uapi_pwm_set_group(PWM_GROUP_ID_L_forword, channel_id_l_forword, 1);  
    uapi_pwm_set_group(PWM_GROUP_ID_L_backword, channel_id_l_backword, 1);  

 

    while(1) {

   ControlCar();
   osal_msleep(10);


    }

     return NULL;

}




static void main_entry(void)
{
    
    sle_uart_entry();
    osThreadAttr_t attr;

    attr.name = "MainTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = PWM_TASK_STACK_SIZE;
    attr.priority = PWM_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)main_task, NULL, &attr) == NULL) {
        /* Create task fail. */
    }
}

/* Run the pwm_entry. */
SYS_RUN(main_entry);


